// 假设您已经有一个用于操作items的ItemDB类
// 导入 MySQL 模块
const mysql = require("mysql");
const util = require("../../common/util");
const config = require("../../common/config");

// 创建 MySQL 连接池
const pool = require("../../common/util");

// 假设您已经有一个用于操作items的ItemDB类
// 导入ReservationDB类
const ItemDB = require("./item");
class ReservationDB {
    /**
     * @constructor
     * @private
     */
    constructor() {
        this.instance = null;
        this.pool = pool;
    }

    /**
     * 创建 ReservationDB 对象
     * @returns {ReservationDB} ReservationDB 实例
     */
    static getInstance() {
        if (!this.instance) {
            this.instance = new ReservationDB();
        }
        return this.instance;
    }
}


// 添加预约
ReservationDB.prototype.add = async function (reservation) {
    try {
      // 判断物品id是否存在
      let item = await ItemDB.getInstance().find(reservation.itemId);
      if (!item) {
        throw new Error(`物品不存在，itemId: ${reservation.itemId}`);
      }
  
      // 构造插入预约的 SQL 语句
      let sql = `INSERT INTO reservations (
        reserver_id, item_id, reservation_time, retrieve_time, note
      ) VALUES (
        ?, ?, ?, ?, ?
      );`;
  
      // 提取预约数据作为参数
      let params = [
        reservation.userId,
        reservation.itemId,
        reservation.reservationTime,
        reservation.retrieveTime,
        reservation.note
      ];
  
      // 使用 query 函数执行 SQL 插入操作
      let result = await this.pool.query(sql, params);
  
      // 返回自增ID
      return result.insertId;
    } catch (err) {
      // 判断是否是外键约束错误
    if (err.code === 'ER_NO_REFERENCED_ROW_2') {
        // 返回更友好的错误响应
        return {
          code: 400, // 或者根据需要设置其他错误代码
          msg: '预约失败，请检查物品ID是否正确',
          data: err
        };
      }
  
      // 记录错误日志
      util.err(`添加预约失败，错误信息：${err.message}`);
      throw err;
    }
  };
  

/**
* 获取预约列表
* @param {Number} [limit=-1] 数量限制
* @param {Number} [offset=-1] 分页偏移
* @returns {Promise<Array<Object>>} 物品列表
*/
ReservationDB.prototype.findAll = async function (limit = -1, offset = -1) {
    try {
        // 构造查询物品列表的 SQL 语句
        let sql = "SELECT * FROM reservations ORDER BY id";
        let params = [];
        if (limit !== -1) {
            sql += " LIMIT ?";
            params.push(limit);

            if (offset !== -1) {
                sql += " OFFSET ?";
                params.push(offset);
            }
        }

        // 使用 query 函数执行 SQL 查询操作
        let result = await this.pool.query(sql, params);

        // 返回查询结果
        return result;
    } catch (err) {
        // 在出现错误时抛出异常
        throw err;
    }
};


// 获取指定ID的预约
ReservationDB.prototype.find = async function (reservationId) {
    try {
        // 构造查询预约的 SQL 语句
        let sql = `SELECT * FROM reservations WHERE id = ?`;
        let params = [reservationId];

        // 使用 query 函数执行 SQL 查询操作
        let result = await this.pool.query(sql, params);

        // 返回查询结果
        return result[0];
    } catch (err) {
        throw err;
    }
}

// 更新预约
ReservationDB.prototype.update = async function (reservation) {
    try {
        // 构造更新预约的 SQL 语句
        let sql = `UPDATE reservations SET
        reservation_time = ?,
        retrieve_time = ?,
        confirmed = ?,
        status = ?,
        note = ?,
        delivery_person_id = ?
      WHERE id = ?;`;

        // 提取预约数据作为参数
        let params = [
            reservation.reservationTime,
            reservation.retrieveTime,
            reservation.confirmed,
            reservation.status,
            reservation.note,
            reservation.deliveryPersonId,
            reservation.id // 最后一个是 WHERE 子句中的 id
        ];

        // 使用 query 函数执行 SQL 更新操作
        let result = await this.pool.query(sql, params);
        console.log(result);
        // 返回受影响的行数
        return result.affectedRows;
    } catch (err) {
        throw err;
    }
}



/**
 * 在数据库中更新一条预约记录，根据前端传递的updateData进行更新
 * @param {Object} updateData 包含要更新的字段及其新值的对象，key为前端字段名，value为新值
 * @returns {Number} 受影响的行数，若更新成功则返回大于0的数字，否则返回0
 */
ReservationDB.prototype.updateSelf = async function (updateData) {
  try {
    /**
     * 字段映射对象，用于将前端传入的字段名映射到数据库字段名
     */
    const fieldMap = {
      'reservationTime': 'reservation_time',
      'retrieveTime': 'retrieve_time',
      'confirmed': 'confirmed'
    };

    // 构造动态的SET子句，仅包含有值的字段
    let setClauses = Object.keys(updateData)
      .filter(key => key !== 'id') // 排除id字段
      .map(key => `${fieldMap[key] || key} = ?`) // 使用映射后的字段名，如果映射不存在则使用原字段名
      .join(', '); // 连接成SET子句

    // 构造完整的SQL语句
    let sql = `UPDATE reservations SET ${setClauses} WHERE id = ?`;

    // 提取参数，包括SET子句中的值和WHERE子句中的id
    let params = Object.values(updateData)
      .filter(value => value !== undefined); // 过滤undefined值
    params.push(updateData.id); // 添加id作为WHERE子句的条件参数


    // 使用query函数执行SQL更新操作
    let result = await this.pool.query(sql, params);
    console.log(result);
    // 检查受影响的行数，如果没有行被真正更新（即affectedRows为0）
    if (result.affectedRows === 0) {
      // 可以抛出一个特定的错误，表示没有数据被修改
      throw new Error('没有数据被修改');
    }
    return result.affectedRows; // 返回受影响的行数
  } catch (err) {
    // 抛出错误，供上层处理
    throw err;
  }
};

/**
* 删除预约
* @param {Number} itemId 预约ID
* @returns {Promise<Number>} 影响的记录数
*/
ReservationDB.prototype.remove = async function (reservationId) {
    try {
        // 构造删除物品的 SQL 语句
        let sql = `DELETE FROM reservations WHERE id = ?`;
        let params = [reservationId];

        // 使用 query 函数执行 SQL 删除操作
        let result = await this.pool.query(sql, params);
        console.log(result);
        // 返回影响的记录数
        return result.affectedRows;
    } catch (err) {
        // 在出现错误时抛出异常
        throw err;
    }
};

module.exports = ReservationDB;
